
//#include "Simplex.h"
//#include "LinProg.h"
#include "Rsimplex.h"

//g++ -std=c++11 Karmarkar.cpp Simplex.cpp kar_main.cpp LinProg.cpp -larmadillo
template<typename type>
void print_vector(vector<type> vec)
{
	for_each(vec.begin(), vec.end(), [](type value){cout<<"\t"<<value<<"\t";});
	cout<<endl;
}

void printTuple(const tuple<vector<double>, string, double> &solutionData)
{
	cout<<"The variables are : ";
	print_vector(get<0>(solutionData));
	cout<<"This solution is : "<<get<1>(solutionData)<<endl;
	cout<<"The optimal value of the objective is : "<<get<2>(solutionData)<<endl;
}
int main()
{
/*
	mat C= {7,12};
	mat A;
	A<<9<<4<<endr
	 <<4<<5<<endr
	 <<3<<10<<endr;
	cout<<A<<endl;
	mat b={360,200,300};
	b.reshape(3,1);

	double magic_number; //high_estimate_of_solution*(number of variables+number of slack for both dual and primal)
	magic_number=2000; //need to find out how to make an estimate of this number
	solve(C,A,b,magic_number);
*/
/*	
    Simplex p;
    p.setMaximum(true);
    p.setObjective( { 3, 1, 5, 4});
    vector<double> eq1 = { 3, -3, 2, 8};
    vector<double> eq2 = { 5, 6, -4, -4 };
    vector<double> eq3 = { 4, -2 , 1, 3 };

    p.setConstraints( { eq1, eq2, eq3});
    p.setInequalitySigns( { "<=", "<=", "<=" });
    p.setInequalityVals( { 50, 40, 20});
    p.setConstrainedVars( {"c","c","c","c"});

    cout << "Primal: " <<endl;
    p.printProgram(p);
    cout << "TESTING: " <<endl;
    //p.convertToSimplexForm (p);
    //tst.printProgram(tst); 
   // tst.print_tableau(tst);
    p.solve();
*/

	LinProg p;	
	p.setMaximum(true);
	p.setObjective( { 3, 5 });
	vector<double> eq1 = { 1, 0 };
	vector<double> eq2 = { 0, 2 };
	vector<double> eq3 = { 3, 2 };
	//vector<double> eq4 = { -2, 2, 1 };
	//vector<double> eq5 = { 3, 0, 0 };
	p.setConstraints( { eq1, eq2, eq3 });
	p.setInequalitySigns( { "<=", "=", ">=" });
	p.setInequalityVals( { 4, 12, 18 });
	p.setConstrainedVars( {true,true});

	Rsimplex rs_problem(p);
	rs_problem.printLinProg()
;	printTuple(rs_problem.solve());

/*
	LinProg p;	// 0 6.5 1
	p.setMaximum(true);
	p.setObjective( { 3, 2, 4 });
	vector<double> eq1 = { 3, 2, 5 };
	vector<double> eq2 = { 4, 2, 3 };
	vector<double> eq3 = { 2, 1, 1 };
	//vector<double> eq4 = { -2, 2, 1 };
	//vector<double> eq5 = { 3, 0, 0 };
	p.setConstraints( { eq1, eq2, eq3 });
	p.setInequalitySigns( { "<=", "<=", ">=" });
	p.setInequalityVals( { 18, 16, 4 });
	p.setConstrainedVars( {true,true,true});

	Rsimplex rs_problem(p);
	printTuple(rs_problem.solve());
*/	
/*
	LinProg p;	//solution: 1.8 and 1.6 and 7
	p.setMaximum(true);
	p.setObjective( { 3, 1 });
	vector<double> eq1 = { 2, -1 };
	vector<double> eq2 = { 1, 2 };
	//vector<double> eq3 = { 3, 2 };
	//vector<double> eq4 = { -2, 2, 1 };
	//vector<double> eq5 = { 3, 0, 0 };
	p.setConstraints( { eq1, eq2 });
	p.setInequalitySigns( { "<=", "<=" });
	p.setInequalityVals( { 2, 5 });
	p.setConstrainedVars( {true,true});
	Rsimplex rs_problem(p);
	printTuple(rs_problem.solve());
*/
	//k_problem.convertToStandardForm();
	//k_problem.convertToStandardForm().printLinProg();	
	//k_problem.printLinProg();	
	//printTuple(k_problem.solve());
	//k_problem.printLinProg();
	//printTuple(k_problem.solve());
	//printTuple(s_problem.solve());
	/*
	print_vector(k_problem.getObjective());
	mat a;
	rowvec aa = conv_to<rowvec>::from(k_problem.getObjective());
	a=aa;	
	//a=join_cols(a,aa);
	//a=join_cols(a,aa);
	//a=join_cols(a,aa);
	cout<<a<<endl;
	//cout<<aa<<endl;

	mat constraintsZ;
	vector< vector<double> > bowl=p.getConstraints();	

	for_each(bowl.begin(),bowl.end(), [&](vector<double> value)
	{
		rowvec temp = conv_to<rowvec>::from(value);
		constraintsZ=join_cols(constraintsZ,temp);
	});

	cout<<constraintsZ<<endl;
	
	mat bVec = conv_to<mat>::from(p.getInequalityVals());
	cout<<bVec<<endl;

	rowvec temp = conv_to<rowvec>::from(p.getObjective());
	mat objectiveC=temp;
	cout<<objectiveC<<endl;
	
	mat bb={360,200,300};
	bb.reshape(3,1);
	cout<<bb<<endl;

	mat valuesB = conv_to<mat>::from(p.getInequalityVals());
	cout<<valuesB<<endl;
	k_problem.setClassVariables(p);

	cout<<k_problem.getObjectiveC()<<endl;
	cout<<k_problem.getConstraintsA()<<endl;
	cout<<k_problem.getValuesB()<<endl;
	*/
/*
	tuple< double, string > test;
	test=make_tuple(12,"arthur");
	cout<<get<0>(test)<<endl;

	vector<double> subzero={1,2,3,4};
	string details="ninja";
	tuple<vector<double>, string> g=make_tuple(subzero, details);
*/
	//auto g=make_tuple(subzero, details);
	
		
}
